<?php
namespace App\Lib;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Models\SmsLog;
use Carbon\Carbon;
use Illuminate\Support\Facades\Redis;

class Sms
{
    const REGISTER_TEMPLATE = 'SMS_169955077'; // 身份验证验证码
    const LOGIN_TEMPLATE    = 'SMS_169955076'; // 登录确认验证码

    /**
     * 发送验证码
     * @param $mobile
     * @param $templateCode
     * @param $ip
     * @param $action
     * @return array
     * @throws ClientException
     * @throws OilcardException
     * @throws ServerException
     */
    public function sendVerifyCode($mobile,$templateCode,$ip,$action)
    {
        AlibabaCloud::accessKeyClient(config('sms.aliyun')['accessKeyId'], config('sms.aliyun')['accessKeySecret'])
            ->regionId('cn-hangzhou') // replace regionId as you need
            ->asDefaultClient();
        $key = md5($mobile.$templateCode);
        if (!Redis::connection('default')->exists($key)){
            $code = mt_rand(0, 9) . mt_rand(10000, 99999);
            Redis::connection('default')->setex($key, 600, $code);
        }
        $code = Redis::connection('default')->get($key);
        $result = AlibabaCloud::rpc()
            ->product('Dysmsapi')
            // ->scheme('https') // https | http
            ->version('2017-05-25')
            ->action('SendSms')
            ->method('POST')
            ->host('dysmsapi.aliyuncs.com')
            ->options([
                'query' => [
                    'RegionId' => "cn-hangzhou",
                    'PhoneNumbers' => $mobile,
                    'SignName' => config('sms.aliyun')['signName'],
                    'TemplateCode' => $templateCode,
                    'TemplateParam' => "{\"code\":".$code."}",
                ],
            ])
            ->request();
        $data = $result->toArray();
        $smsLog = new SmsLog();
        $smsLog->mobile = $mobile;
        $smsLog->content = '{"code":"'.$code.'"}';
        $smsLog->is_success = $data['Code']=='OK'??0;
        $smsLog->result = json_encode($data);
        $smsLog->ip = $ip;
        $smsLog->action = $action;
        $smsLog->created_at = Carbon::now();
        $smsLog->save();
        if ($data['Code']!='OK'){
            throw new OilcardException("验证码发送失败");
        }
        return $data;
    }

    /**
     * 短信验证
     * @param $mobile
     * @param $smsCode
     * @param $templateCode
     * @return bool
     */
    public static function verify($mobile,$smsCode,$templateCode)
    {
        $key = md5($mobile.$templateCode);
        if (!Redis::connection('default')->exists($key)){
            return false;
        }
        $code = Redis::connection('default')->get($key);
        if ($smsCode!=$code){
            return false;
        }
        Redis::connection('default')->del($key);
        return true;
    }
}